PHP 本地文件包含 RCE 与 PHPINFO
在PHP文件包含漏洞中,当我们找不到一个有效的文件来包含触发RCE时,如果存在PHPINFO可以告诉我们临时文件的随机生成的文件名及其位置,我们可能能够包含一个临时文件来利用它.
参考:
漏洞利用细节
目标环境是最新的PHP 7.2,这告诉我们无论版本如何,都存在此漏洞。
环境启动后,访问http://192.168.44.132:8080/phpinfo.php
获取PHPINFO页面,http://192.168.44.132:8080/lfi.php?file=/etc/passwd
显示存在LFI漏洞。
当向 PHP 发送 POST 请求并且该请求包含一个 FILE 块时,PHP 会将发布的文件保存到一个临时文件中(通常为/tmp/php[6 random digits]
),文件名可以在$_FILES
变量中找到。请求结束后,此临时文件将被删除。
同时,PHPINFO 页面会打印上下文中的所有变量,包括$_FILES
. 因此,如果我们将 POST 请求发送到 PHPINFO 页面,则可以在响应中找到临时文件的名称。
通过这种方式,LFI 漏洞可以在没有可用的本地文件的情况下升级为 RCE。
文件包含和 PHPINFO 通常位于不同的网页中。理论上,我们需要在PHPINFO页面的文件上传请求的响应中检索到文件名后将文件名发送到文件包含页面。但是,在第一个请求完成后,该文件将从磁盘中删除,因此我们需要赢得比赛。
脚步:
- 将文件上传请求发送到 PHPINFO 页面,其中 HEADER 和 GET 字段填充了大量垃圾数据。
- 响应内容会很大,因为 PHPINFO 会打印出所有数据。
- PHP 的默认输出缓冲区大小是 4096 字节。可以理解为PHP在一次socket连接过程中每次返回4096字节。
- 所以我们使用原始套接字来实现我们的目标。每次我们读取 4096 个字节并将文件名发送到 LFI 页面。
- 当我们得到文件名时,第一个套接字连接还没有结束,这意味着临时文件在那个时候仍然存在。
- 通过利用时间间隔,可以包含和执行临时文件。
漏洞复现
python脚本exp.py实现了上述过程。成功包含临时文件后,<?php file_put_contents('/tmp/g', '<?=eval($_REQUEST[1])?>')?>
将执行以生成永久文件/tmp/g
以供进一步使用。
使用python2:python exp.py 192.168.44.132 8080 100
:
脚本在第10个数据包成功,之后可以执行任意代码: